﻿#pragma once

#include "Exception.h"

#include <string>
#include <vector>
#include <cstdint>
#include <cstdint>

namespace Lisp
{

  namespace StringUtils
  {
    std::string Trim(const std::string &str);

    std::string Escape(const std::string &str);
    std::string Unescape(const std::string &str);

    template <typename... Args>
    std::string Format(const std::string &fmt, Args... args)
    {
      int size = snprintf(nullptr, 0, fmt.c_str(), args...);
      std::string result(size + 1, '\0');
      snprintf(&result[0], size + 1, fmt.c_str(), args...);
      return result;
    }

  }

  namespace FileUtils
  {
    std::string ReadFile(const std::string &path);
    std::vector<std::string> ListFiles(const std::string &path, const std::string &ext);
  }

  namespace TimeUtils
  {
    int64_t Now();
  }

} // namespace Lisp

#define LISP_CHECK(condition, ...) if (!(condition)){throw Lisp::RuntimeException(Lisp::StringUtils::Format(__VA_ARGS__)); }